/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
 *
 * @file    sample_public_disp.c
 * @brief   sample public disp module
 * @author  HiMobileCam NDK develop team
 * @date  2019-5-16
 */

#include "sample_cfg.h"
#include "sample_public_disp.h"


#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */

#ifdef SUPPORT_HDMI
HI_VOID SAMPLE_COMM_EventPro(HI_HDMI_EVENT_TYPE_E event, HI_VOID *pPrivateData)
{
    switch (event) {
        case HI_HDMI_EVENT_HOTPLUG:
            printf("\033[0;32mhdmi HOTPLUG event! \033[0;39m\n");
            break;

        case HI_HDMI_EVENT_NO_PLUG:
            printf("\033[0;31mhdmi NO_PLUG event! \033[0;39m\n");
            break;

        default:
            printf("\033[0;31minvalid hdmi event! \033[0;39m\n");
            break;
    }
}
#endif

HI_S32 SAMPLE_COMM_StartHdmi(HI_VOID)
{
#ifdef SUPPORT_HDMI
    HI_S32 s32Ret = HI_SUCCESS;
    /* starts HDMI */
    HI_MAPI_HDMI_ATTR_S sthdmiattr;
    HI_HANDLE HdmiHdl = SAMPLE_MAPI_HDMI_HANDLE;
    HI_HDMI_CALLBACK_FUNC_S stHdmiCallBackFunc;

    stHdmiCallBackFunc.pfnHdmiEventCallback = (HI_HDMI_CallBack)SAMPLE_COMM_EventPro;
    stHdmiCallBackFunc.pPrivateData = HI_NULL;

    SAMPLE_CHECK_RET(memset_s(&sthdmiattr, sizeof(HI_MAPI_HDMI_ATTR_S), 0, sizeof(HI_MAPI_HDMI_ATTR_S)));
    sthdmiattr.bEnableHdmi = HI_TRUE;
    sthdmiattr.bEnableVideo = HI_TRUE;
    sthdmiattr.enHdmiSync = VO_OUTPUT_1080P30;
    sthdmiattr.bEnableAudio = HI_FALSE;
    sthdmiattr.enSampleRate = AUDIO_SAMPLE_RATE_48000;

    SAMPLE_CHECK_GOTO(HI_MAPI_HDMI_Init(HdmiHdl, &stHdmiCallBackFunc));
    SAMPLE_CHECK_GOTO(HI_MAPI_HDMI_SetAttr(HdmiHdl, &sthdmiattr));
    SAMPLE_CHECK_GOTO(HI_MAPI_HDMI_Start(HdmiHdl));
exit:
    return s32Ret;
#endif
    return HI_SUCCESS;
}

HI_VOID SAMPLE_COMM_StopHdmi(HI_HANDLE HdmiHdl)
{
#ifdef SUPPORT_HDMI
    HI_MAPI_HDMI_Stop(HdmiHdl);
    HI_MAPI_HDMI_Deinit(HdmiHdl);
#endif
}

HI_S32 SAMPLE_COMM_StartPreview(HI_HANDLE GrpHdl, HI_HANDLE PortHdl, HI_BOOL bStitch)
{
    /* start disp */
    HI_S32 s32Ret = HI_SUCCESS;
    HI_HANDLE DispHdl = SAMPLE_MAPI_DISP_HANDLE;
    HI_MAPI_DISP_ATTR_S stDispAttr = {0};
    HI_MAPI_DISP_VIDEOLAYER_ATTR_S stVideoLayerAttr = {0};

    stDispAttr.stPubAttr.u32BgColor = 0xFF;
    stDispAttr.stPubAttr.enIntfType = VO_INTF_HDMI;
    stDispAttr.stPubAttr.enIntfSync = VO_OUTPUT_1080P30;
    SAMPLE_CHECK_RET(memset_s(&stDispAttr.stPubAttr.stSyncInfo, sizeof(VO_SYNC_INFO_S), 0, sizeof(VO_SYNC_INFO_S)));
    SAMPLE_CHECK_RET(memset_s(&stVideoLayerAttr, sizeof(HI_MAPI_DISP_VIDEOLAYER_ATTR_S), 0,
        sizeof(HI_MAPI_DISP_VIDEOLAYER_ATTR_S)));
    // 3: VideoLayer buf len
    stVideoLayerAttr.u32BufLen = SAMPLE_MAPI_DISP_VIDEO_LAYER_BUF_LEN;
    SAMPLE_CHECK_GOTO(HI_MAPI_DISP_Init(DispHdl, &stDispAttr));
    SAMPLE_CHECK_GOTO(HI_MAPI_DISP_Start(DispHdl, &stVideoLayerAttr));

    SAMPLE_CHECK_GOTO(SAMPLE_COMM_StartHdmi());

    /* start window */
    HI_MAPI_DISP_WINDOW_ATTR_S stWndAttr;
    HI_HANDLE WndHdl = SAMPLE_MAPI_WIND_HANDLE;

    stWndAttr.stRect.s32X = 0;
    stWndAttr.stRect.s32Y = 0;
    stWndAttr.stRect.u32Width = 1920;
    stWndAttr.stRect.u32Height = 1080;
    stWndAttr.u32Priority = 0;
    SAMPLE_CHECK_GOTO(HI_MAPI_DISP_SetWindowAttr(DispHdl, WndHdl, &stWndAttr));
    SAMPLE_CHECK_GOTO(HI_MAPI_DISP_StartWindow(DispHdl, WndHdl));
    SAMPLE_CHECK_GOTO(HI_MAPI_DISP_Bind_VProc(GrpHdl, PortHdl, DispHdl, WndHdl, bStitch));
exit:
    return s32Ret;
}

HI_VOID SAMPLE_COMM_StopPreview(HI_HANDLE GrpHdl, HI_HANDLE PortHdl, HI_BOOL bStitch)
{
    /* start disp */
    HI_HANDLE DispHdl = SAMPLE_MAPI_DISP_HANDLE;
    HI_HANDLE HdmiHdl = SAMPLE_MAPI_HDMI_HANDLE;
    HI_HANDLE WndHdl = SAMPLE_MAPI_WIND_HANDLE;

    HI_MAPI_DISP_UnBind_VProc(GrpHdl, PortHdl, DispHdl, WndHdl, bStitch);
    HI_MAPI_DISP_StopWindow(DispHdl, WndHdl);
    SAMPLE_COMM_StopHdmi(HdmiHdl);
    HI_MAPI_DISP_Stop(DispHdl);
    HI_MAPI_DISP_Deinit(DispHdl);
}

HI_S32 SAMPLE_GetWindowSize(VO_PUB_ATTR_S *pstPubAttr, HI_U32 *pu32Width, HI_U32 *pu32Height)
{
    HI_U32 u32Width = 0;
    HI_U32 u32Height = 0;

    switch (pstPubAttr->enIntfSync) {
        case VO_OUTPUT_PAL:
            u32Width = 720;
            u32Height = 576;
            break;

        case VO_OUTPUT_NTSC:
            u32Width = 720;
            u32Height = 480;
            break;

        case VO_OUTPUT_1080P24:
            u32Width = 1920;
            u32Height = 1080;
            break;

        case VO_OUTPUT_1080P25:
            u32Width = 1920;
            u32Height = 1080;
            break;

        case VO_OUTPUT_1080P30:
            u32Width = 1920;
            u32Height = 1080;
            break;

        case VO_OUTPUT_720P50:
            u32Width = 1280;
            u32Height = 720;
            break;

        case VO_OUTPUT_720P60:
            u32Width = 1280;
            u32Height = 720;
            break;

        case VO_OUTPUT_1080I50:
            u32Width = 1920;
            u32Height = 1080;
            break;

        case VO_OUTPUT_1080I60:
            u32Width = 1920;
            u32Height = 1080;
            break;

        case VO_OUTPUT_1080P50:
            u32Width = 1920;
            u32Height = 1080;
            break;

        case VO_OUTPUT_1080P60:
            u32Width = 1920;
            u32Height = 1080;
            break;

        case VO_OUTPUT_576P50:
            u32Width = 720;
            u32Height = 576;
            break;

        case VO_OUTPUT_480P60:
            u32Width = 720;
            u32Height = 480;
            break;

        case VO_OUTPUT_800x600_60:
            u32Width = 800;
            u32Height = 600;
            break;

        case VO_OUTPUT_1024x768_60:
            u32Width = 1024;
            u32Height = 768;
            break;

        case VO_OUTPUT_1280x1024_60:
            u32Width = 1280;
            u32Height = 1024;
            break;

        case VO_OUTPUT_1366x768_60:
            u32Width = 1366;
            u32Height = 768;
            break;

        case VO_OUTPUT_1440x900_60:
            u32Width = 1440;
            u32Height = 900;
            break;

        case VO_OUTPUT_1280x800_60:
            u32Width = 1280;
            u32Height = 800;
            break;

        case VO_OUTPUT_1600x1200_60:
            u32Width = 1600;
            u32Height = 1200;
            break;

        case VO_OUTPUT_1680x1050_60:
            u32Width = 1680;
            u32Height = 1050;
            break;

        case VO_OUTPUT_1920x1200_60:
            u32Width = 1920;
            u32Height = 1200;
            break;

        case VO_OUTPUT_640x480_60:
            u32Width = 640;
            u32Height = 480;
            break;

        case VO_OUTPUT_960H_PAL:
            u32Width = 960;
            u32Height = 576;
            break;

        case VO_OUTPUT_960H_NTSC:
            u32Width = 960;
            u32Height = 480;
            break;

        case VO_OUTPUT_1920x2160_30:
            u32Width = 1920;
            u32Height = 2160;
            break;

        case VO_OUTPUT_2560x1440_30:
            u32Width = 2560;
            u32Height = 1440;
            break;

        case VO_OUTPUT_2560x1600_60:
            u32Width = 2560;
            u32Height = 1600;
            break;

        case VO_OUTPUT_3840x2160_24:
            u32Width = 3840;
            u32Height = 2160;
            break;

        case VO_OUTPUT_3840x2160_25:
            u32Width = 3840;
            u32Height = 2160;
            break;

        case VO_OUTPUT_3840x2160_30:
            u32Width = 3840;
            u32Height = 2160;
            break;

        case VO_OUTPUT_3840x2160_50:
            u32Width = 3840;
            u32Height = 2160;
            break;

        case VO_OUTPUT_3840x2160_60:
            u32Width = 3840;
            u32Height = 2160;
            break;

        case VO_OUTPUT_4096x2160_24:
            u32Width = 4096;
            u32Height = 2160;
            break;

        case VO_OUTPUT_4096x2160_25:
            u32Width = 4096;
            u32Height = 2160;
            break;

        case VO_OUTPUT_4096x2160_30:
            u32Width = 4096;
            u32Height = 2160;
            break;

        case VO_OUTPUT_4096x2160_50:
            u32Width = 4096;
            u32Height = 2160;
            break;

        case VO_OUTPUT_4096x2160_60:
            u32Width = 4096;
            u32Height = 2160;
            break;

        case VO_OUTPUT_320x240_60:
            u32Width = 320;
            u32Height = 240;
            break;

        case VO_OUTPUT_320x240_50:
            u32Width = 320;
            u32Height = 240;
            break;

        case VO_OUTPUT_240x320_50:
            u32Width = 240;
            u32Height = 320;
            break;

        case VO_OUTPUT_240x320_60:
            u32Width = 240;
            u32Height = 320;
            break;

        case VO_OUTPUT_800x600_50:
            u32Width = 800;
            u32Height = 600;
            break;

        case VO_OUTPUT_720x1280_60:
            u32Width = 720;
            u32Height = 1280;
            break;

        case VO_OUTPUT_1080x1920_60:
            u32Width = 1080;
            u32Height = 1920;
            break;

        case VO_OUTPUT_7680x4320_30:
            u32Width = 7680;
            u32Height = 4320;
            break;

        case VO_OUTPUT_USER:
            u32Width = pstPubAttr->stSyncInfo.u16Hact;  // stSyncInfo.u16Hact;
            u32Height = (pstPubAttr->stSyncInfo.bIop) ? pstPubAttr->stSyncInfo.u16Vact :
                pstPubAttr->stSyncInfo.u16Vact * 2;
            break;

        default:
            printf("sample_GetwindowSize ERR\n");
            break;
    }

    *pu32Width = u32Width;
    *pu32Height = u32Height;

    return HI_SUCCESS;
}

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
